package com.autoagent.ai_live_master.webSocket.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.autoagent.ai_live_master.webSocket.vo.TokenResponse;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TokenService {
    private final static String TIME_ZONE = "GMT";
    private final static String FORMAT_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private final static String URL_ENCODING = "UTF-8";
    private static final String ALGORITHM_NAME = "HmacSHA1";
    private static final String ENCODING = "UTF-8";

    public TokenResponse getToken(String accessKeyId, String accessKeySecret) {
        try {
            // 所有请求参数
            Map<String, String> queryParamsMap = new HashMap<>();
            queryParamsMap.put("AccessKeyId", accessKeyId);
            queryParamsMap.put("Action", "CreateToken");
            queryParamsMap.put("Version", "2019-02-28");
            queryParamsMap.put("Timestamp", getISO8601Time(null));
            queryParamsMap.put("Format", "JSON");
            queryParamsMap.put("RegionId", "cn-shanghai");
            queryParamsMap.put("SignatureMethod", "HMAC-SHA1");
            queryParamsMap.put("SignatureVersion", "1.0");
            queryParamsMap.put("SignatureNonce", getUniqueNonce());

            String queryString = canonicalizedQuery(queryParamsMap);
            String method = "GET";
            String urlPath = "/";
            String stringToSign = createStringToSign(method, urlPath, queryString);
            String signature = sign(stringToSign, accessKeySecret + "&");
            String queryStringWithSign = "Signature=" + signature + "&" + queryString;

            String url = "http://nls-meta.cn-shanghai.aliyuncs.com/?" + queryStringWithSign;
            Request request = new Request.Builder()
                    .url(url)
                    .header("Accept", "application/json")
                    .get()
                    .build();

            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            String result = response.body().string();

            if (response.isSuccessful()) {
                JSONObject rootObj = JSON.parseObject(result);
                JSONObject tokenObj = rootObj.getJSONObject("Token");
                if (tokenObj != null) {
                    TokenResponse tokenResponse = new TokenResponse();
                    tokenResponse.setToken(tokenObj.getString("Id"));
                    tokenResponse.setExpireTime(tokenObj.getLongValue("ExpireTime"));
                    
                    // 将时间戳转换为北京时间
                    String expireDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                            .format(new Date(tokenResponse.getExpireTime() * 1000));
                    tokenResponse.setExpireDate(expireDate);
                    
                    return tokenResponse;
                }
            }
            throw new RuntimeException("获取Token失败: " + result);
        } catch (Exception e) {
            throw new RuntimeException("获取Token异常", e);
        }
    }

    private String getISO8601Time(Date date) {
        Date nowDate = date;
        if (null == date) {
            nowDate = new Date();
        }
        SimpleDateFormat df = new SimpleDateFormat(FORMAT_ISO8601);
        df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
        return df.format(nowDate);
    }

    private String getUniqueNonce() {
        return UUID.randomUUID().toString();
    }

    private String percentEncode(String value) throws UnsupportedEncodingException {
        return value != null ? URLEncoder.encode(value, URL_ENCODING)
                .replace("+", "%20")
                .replace("*", "%2A")
                .replace("%7E", "~") : null;
    }

    private String canonicalizedQuery(Map<String, String> queryParamsMap) throws UnsupportedEncodingException {
        String[] sortedKeys = queryParamsMap.keySet().toArray(new String[]{});
        Arrays.sort(sortedKeys);
        StringBuilder canonicalizedQueryString = new StringBuilder();
        for (String key : sortedKeys) {
            canonicalizedQueryString.append("&")
                    .append(percentEncode(key)).append("=")
                    .append(percentEncode(queryParamsMap.get(key)));
        }
        return canonicalizedQueryString.toString().substring(1);
    }

    private String createStringToSign(String method, String urlPath, String queryString) throws UnsupportedEncodingException {
        StringBuilder strBuilderSign = new StringBuilder();
        strBuilderSign.append(method);
        strBuilderSign.append("&");
        strBuilderSign.append(percentEncode(urlPath));
        strBuilderSign.append("&");
        strBuilderSign.append(percentEncode(queryString));
        return strBuilderSign.toString();
    }

    private String sign(String stringToSign, String accessKeySecret) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        Mac mac = Mac.getInstance(ALGORITHM_NAME);
        mac.init(new SecretKeySpec(accessKeySecret.getBytes(ENCODING), ALGORITHM_NAME));
        byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
        String signBase64 = DatatypeConverter.printBase64Binary(signData);
        return percentEncode(signBase64);
    }
} 